package com.ruoyi.standingbook.sorting.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.asset.homepage.enums.ServiceTypeEnum;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.domain.vo.SortingErecordVo;
import com.ruoyi.common.domain.vo.StatisticsSortingVo;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.standingbook.sorting.domain.Sorting;
import com.ruoyi.standingbook.sorting.domain.bo.SortingBo;
import com.ruoyi.standingbook.sorting.domain.bo.SortingPicBo;
import com.ruoyi.standingbook.sorting.domain.vo.SortingImportDetailVo;
import com.ruoyi.standingbook.sorting.domain.vo.SortingPicVo;
import com.ruoyi.standingbook.sorting.domain.vo.SortingVo;
import com.ruoyi.standingbook.sorting.mapper.SortingMapper;
import com.ruoyi.standingbook.sorting.service.ISortingService;
import lombok.RequiredArgsConstructor;
import org.apache.http.client.utils.DateUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 垃圾分类督导Service业务层处理
 *
 * @author cc
 * @date 2023-05-01
 */
@RequiredArgsConstructor
@Service
public class SortingServiceImpl implements ISortingService {

    private final SortingMapper baseMapper;

    /**
     * 查询垃圾分类督导
     */
    @Override
    public SortingVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询垃圾分类督导列表
     */
    @Override
    public TableDataInfo<SortingVo> queryPageList(SortingBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Sorting> lqw = buildQueryWrapper(bo);
        Page<SortingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询垃圾分类督导列表
     */
    @Override
    public List<SortingVo> queryList(SortingBo bo) {
        LambdaQueryWrapper<Sorting> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询Excel垃圾分类督导列表
     */
    @Override
    public List<SortingVo> queryExcelList(SortingBo bo) {
        LambdaQueryWrapper<Sorting> lqw = buildExcelQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Sorting> buildQueryWrapper(SortingBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Sorting> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getItemName()), Sorting::getItemName, bo.getItemName());
        lqw.eq(StringUtils.isNotBlank(bo.getCommunity()), Sorting::getCommunity, bo.getCommunity());
        lqw.like(StringUtils.isNotBlank(bo.getSuperintendentUserName()), Sorting::getSuperintendentUserName, bo.getSuperintendentUserName());
        lqw.like(StringUtils.isNotBlank(bo.getDeliveryName()), Sorting::getDeliveryName, bo.getDeliveryName());

//        lqw.like(StringUtils.isNotBlank(bo.getCollectionName()), Sorting::getCollectionName, bo.getCollectionName());
//        lqw.eq(StringUtils.isNotBlank(bo.getSuperintendentUserPhone()), Sorting::getSuperintendentUserPhone, bo.getSuperintendentUserPhone());
//        lqw.eq(StringUtils.isNotBlank(bo.getDepartment()), Sorting::getDepartment, bo.getDepartment());
//        lqw.like(StringUtils.isNotBlank(bo.getSupervisorManagerUserName()), Sorting::getSupervisorManagerUserName, bo.getSupervisorManagerUserName());
//        lqw.eq(StringUtils.isNotBlank(bo.getSupervisorManagerUserPhone()), Sorting::getSupervisorManagerUserPhone, bo.getSupervisorManagerUserPhone());
//        lqw.eq(StringUtils.isNotBlank(bo.getGpsStatus()), Sorting::getGpsStatus, bo.getGpsStatus());
//        lqw.eq(StringUtils.isNotBlank(bo.getCheckStatus()), Sorting::getCheckStatus, bo.getCheckStatus());

        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
            Sorting::getDate ,params.get("beginTime"), params.get("endTime"));

        lqw.orderByDesc(Sorting::getCreateTime);
        lqw.orderByDesc(Sorting::getDate);

        return lqw;
    }

    private LambdaQueryWrapper<Sorting> buildExcelQueryWrapper(SortingBo bo) {
        Map<String, Object> params = bo.getParams();
        if(params.get("endDate") == null){
            params.put("endDate", DateUtils.formatDate(new Date(), "yyyy-MM-dd"));
        }
        LambdaQueryWrapper<Sorting> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getCommunity()), Sorting::getCommunity, bo.getCommunity());
        lqw.eq(params.get("endDate") != null, Sorting::getDate , params.get("endDate").toString().substring(0,10));
        lqw.orderByDesc(Sorting::getCreateTime);
        lqw.orderByDesc(Sorting::getDate);
        return lqw;
    }

    /**
     * 新增垃圾分类督导
     */
    @Override
    public Boolean insertByBo(SortingBo bo) {
        Sorting add = BeanUtil.toBean(bo, Sorting.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改垃圾分类督导
     */
    @Override
    public Boolean updateByBo(SortingBo bo) {
        Sorting update = BeanUtil.toBean(bo, Sorting.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Sorting entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除垃圾分类督导
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 批量插入
     */
    @Override
    public Boolean batchInsert(List<SortingImportDetailVo> voList) {
        if (null != voList && !voList.isEmpty()) {
            Date date = voList.get(0).getDate();
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            LambdaQueryWrapper<Sorting> lqw = Wrappers.lambdaQuery();
            lqw.eq(Sorting::getDate, date);
            this.baseMapper.delete(lqw);
        }

        List<Sorting> list = BeanCopyUtils.copyList(voList, Sorting.class);
        list.forEach(e -> {
            e.setId(null);
            e.restBase();
        });
        return this.baseMapper.insertBatch(list);
    }

    /**
     * 获取垃圾分类督导电子档案信息
     *
     * @param bo
     * @return
     */
    public SortingErecordVo getSortingErecordInfo(SortingBo bo) {
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(bo.getDate())) {
            throw new RuntimeException("日期不能为空");
        }
        SortingErecordVo sev = new SortingErecordVo();

        List<StatisticsSortingVo> communityList = baseMapper.statisticsCommunityList(); //市政公厕管养社区列表
        List<StatisticsSortingVo> numList = new ArrayList<>(); //查询统计督导收集点数量、督导投放点数量
        List<StatisticsSortingVo> sortingTodayList = new ArrayList<>(); //垃圾分类督导养今日统计列表
        List<StatisticsSortingVo> sortingMonthList = new ArrayList<>(); //垃圾分类督导养月统计列表
        Integer totalDeliveryNum = 0; //合计督导投放点数量
        Integer totalCollectionNum = 0; //合计督导收集点数量
        Double totalTodayDuration = 0d; //合计今日督导时长
        Double totalThisMonthDuration = 0d; //合计本月累计督导时长
        Double totalTodayNum = 0d;  //统计所有今日总数量
        Double completionToadyNum = 0d; //统计所有今日完成督导的数量
        Double totalTodayCompletionRatio = 0d; //合计今日督导完成比例
        Double totalMonthNum = 0d;  //统计所有本月总数量
        Double completionMonthNum = 0d; //统计所有本月完成督导的数量
        Double totalThisMonthCompletionRatio = 0d; //合计本月累计督导完成比例
        boolean communityFlag1 = false;
        boolean communityFlag2 = false;
        boolean communityFlag3 = false;
        boolean communityFlag4 = false;
        for (StatisticsSortingVo ssv : communityList) {
            bo.setCommunity(ssv.getCommunity());
            //督导投放点数量
            List<StatisticsSortingVo> deliveryNumList = baseMapper.statisticsDeliveryNumList(bo);
            StatisticsSortingVo statisticsSortingVo = new StatisticsSortingVo();
            statisticsSortingVo.setCommunity(ssv.getCommunity());
            if (CollectionUtils.isNotEmpty(deliveryNumList)) {
                statisticsSortingVo.setDeliveryNum(deliveryNumList.get(0).getDeliveryNum());
            } else {
                statisticsSortingVo.setDeliveryNum(0);
            }
            totalDeliveryNum += statisticsSortingVo.getDeliveryNum();
            //督导收集点数量
            List<StatisticsSortingVo> collectionNumList = baseMapper.statisticsCollectionNumList(bo);
            if (CollectionUtils.isNotEmpty(collectionNumList)) {
                statisticsSortingVo.setCollectionNum(collectionNumList.get(0).getCollectionNum());
            } else {
                statisticsSortingVo.setCollectionNum(0);
            }
            totalCollectionNum += statisticsSortingVo.getCollectionNum();
            numList.add(statisticsSortingVo);
            if (ssv.getCommunity().equals("田寮社区")) {
                communityFlag1 = true;
            } else if (ssv.getCommunity().equals("玉律社区")) {
                communityFlag2 = true;
            } else if (ssv.getCommunity().equals("长圳社区")) {
                communityFlag3 = true;
            } else if (ssv.getCommunity().equals("红星社区")) {
                communityFlag4 = true;
            }
        }

        if (!communityFlag1) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("田寮社区");
            ssv.setDeliveryNum(0);
            ssv.setCollectionNum(0);
            communityList.add(ssv);
        }
        if (!communityFlag2) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("玉律社区");
            ssv.setDeliveryNum(0);
            ssv.setCollectionNum(0);
            communityList.add(ssv);
        }
        if (!communityFlag3) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("长圳社区");
            ssv.setDeliveryNum(0);
            ssv.setCollectionNum(0);
            communityList.add(ssv);
        }
        if (!communityFlag4) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("红星社区");
            ssv.setDeliveryNum(0);
            ssv.setCollectionNum(0);
            communityList.add(ssv);
        }


        sortingTodayList = baseMapper.statisticsTodayDurationList(); //统计今天督导时长分组列表
        communityFlag1 = false;
        communityFlag2 = false;
        communityFlag3 = false;
        communityFlag4 = false;
        for (StatisticsSortingVo ssv : sortingTodayList) {
            bo.setCommunity(ssv.getCommunity());
            Double totalNum = 0d;  //总数量
            Double completionNum = 0d; //完成督导的数量
            Double completionRatio = 0d;//督导完成比例
            totalTodayDuration += ssv.getActualDuration();
            List<StatisticsSortingVo> todayCompletionList = baseMapper.statisticsTodayCompletionList(bo);         //统计今天完成督导的数量
            List<StatisticsSortingVo> todayNotCompletionList = baseMapper.statisticsTodayNotCompletionList(bo);  //统计今天未完成督导的数量
            if (CollectionUtils.isNotEmpty(todayCompletionList)) {
                completionNum = todayCompletionList.get(0).getCompletionNum();
                totalNum += completionNum;
                completionToadyNum += completionNum;
                totalTodayNum += completionNum;
            }
            if (CollectionUtils.isNotEmpty(todayNotCompletionList)) {
                Double notCompletionNum = todayNotCompletionList.get(0).getNotCompletionNum();
                totalNum += notCompletionNum;
                totalTodayNum += notCompletionNum;
            }
            completionRatio = (completionNum / totalNum) * 100;  //督导完成比例
            ssv.setCompletionRatio(completionRatio);

            if (ssv.getCommunity().equals("田寮社区")) {
                communityFlag1 = true;
            } else if (ssv.getCommunity().equals("玉律社区")) {
                communityFlag2 = true;
            } else if (ssv.getCommunity().equals("长圳社区")) {
                communityFlag3 = true;
            } else if (ssv.getCommunity().equals("红星社区")) {
                communityFlag4 = true;
            }
        }

        if (!communityFlag1) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("田寮社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingTodayList.add(ssv);
        }
        if (!communityFlag2) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("玉律社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingTodayList.add(ssv);
        }
        if (!communityFlag3) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("长圳社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingTodayList.add(ssv);
        }
        if (!communityFlag4) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("红星社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingTodayList.add(ssv);
        }


        totalTodayCompletionRatio = completionToadyNum != 0 ? (completionToadyNum / totalTodayNum) * 100 : 0;  //合计今日督导完成比例

        sortingMonthList = baseMapper.statisticsMonthDurationList(bo); //统计指定月督导时长分组列表
        communityFlag1 = false;
        communityFlag2 = false;
        communityFlag3 = false;
        communityFlag4 = false;
        for (StatisticsSortingVo ssv : sortingMonthList) {
            bo.setCommunity(ssv.getCommunity());
            Double totalNum = 0d;  //总数量
            Double completionNum = 0d; //完成督导的数量
            Double completionRatio = 0d;//督导完成比例
            totalThisMonthDuration += ssv.getActualDuration();
            List<StatisticsSortingVo> monthCompletionList = baseMapper.statisticsMonthCompletionList(bo);         //统计本月完成督导的数量
            List<StatisticsSortingVo> monthNotCompletionList = baseMapper.statisticsMonthNotCompletionList(bo);  //统计本月未完成督导的数量
            if (CollectionUtils.isNotEmpty(monthCompletionList)) {
                completionNum = monthCompletionList.get(0).getCompletionNum();
                totalNum += completionNum;
                totalMonthNum += completionNum;
                completionMonthNum += completionNum;
            }
            if (CollectionUtils.isNotEmpty(monthNotCompletionList)) {
                Double notCompletionNum = monthNotCompletionList.get(0).getNotCompletionNum();
                totalNum += notCompletionNum;
                totalMonthNum += notCompletionNum;
            }
            completionRatio = (completionNum / totalNum) * 100;  //督导完成比例
            ssv.setCompletionRatio(completionRatio);

            if (ssv.getCommunity().equals("田寮社区")) {
                communityFlag1 = true;
            } else if (ssv.getCommunity().equals("玉律社区")) {
                communityFlag2 = true;
            } else if (ssv.getCommunity().equals("长圳社区")) {
                communityFlag3 = true;
            } else if (ssv.getCommunity().equals("红星社区")) {
                communityFlag4 = true;
            }
        }

        //合并月数据到今日统计列表
        for (StatisticsSortingVo ssv : sortingMonthList) {
            for (StatisticsSortingVo ssv2 : sortingTodayList) {
                if (ssv.getCommunity().equals(ssv2.getCommunity())) {
                    ssv2.setThisMonthDuration(ssv.getActualDuration());
                    ssv2.setThisMonthCompletionRatio(ssv.getCompletionRatio().intValue());
                    break;
                }
            }
        }

        if (!communityFlag1) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("田寮社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingMonthList.add(ssv);
        }
        if (!communityFlag2) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("玉律社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingMonthList.add(ssv);
        }
        if (!communityFlag3) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("长圳社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingMonthList.add(ssv);
        }
        if (!communityFlag4) {
            StatisticsSortingVo ssv = new StatisticsSortingVo();
            ssv.setCommunity("红星社区");
            ssv.setActualDuration(0d);
            ssv.setCompletionRatio(0d);
            sortingMonthList.add(ssv);
        }

        totalThisMonthCompletionRatio = completionMonthNum != 0 ? (completionMonthNum / totalMonthNum) * 100 : 0;   //合计本月督导完成比例

        sev.setSortingNumList(numList);             //垃圾分类督导投放点、收集点数量列表
        sev.setSortingTodayList(sortingTodayList);  //垃圾分类督导养今日统计列表
        sev.setSortingMonthList(sortingMonthList);  //垃圾分类督导养月统计列表
        sev.setTotalDeliveryNum(totalDeliveryNum);  //合计督导投放点数量
        sev.setTotalCollectionNum(totalCollectionNum); //合计督导收集点数量
        sev.setTotalTodayDuration(totalTodayDuration); //合计今日督导时长
        sev.setTotalThisMonthDuration(totalThisMonthDuration);//合计本月累计督导时长
        sev.setTotalTodayCompletionRatio(totalTodayCompletionRatio.intValue()); //合计今日督导完成比例
        sev.setTotalThisMonthCompletionRatio(totalThisMonthCompletionRatio.intValue());//合计本月累计督导完成比例
        return  sev;
    }

    @Override
    public List<SortingPicVo> getTrainingPicByDate(String date) {
        List<SortingPicBo> sortingPicBos = baseMapper.selectPicByDate(date);
        List<SortingPicVo> pics = new ArrayList<>();
        sortingPicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic1())){
                SortingPicVo sortingPicVo = new SortingPicVo();
                sortingPicVo.setPic(e.getPic1());
                pics.add(sortingPicVo);
            }
            if (StringUtils.isNotBlank(e.getPic2())){
                SortingPicVo sortingPicVo = new SortingPicVo();
                sortingPicVo.setPic(e.getPic2());
                pics.add(sortingPicVo);
            }
        });
        return pics;
    }

    @Override
    public List<SortingPicVo> getSupervisePicByDate(String date) {
        List<SortingPicBo> sortingPicBos = baseMapper.selectPicByDate(date);
        List<SortingPicVo> pics = new ArrayList<>();
        sortingPicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic3())){
                SortingPicVo sortingPicVo = new SortingPicVo();
                sortingPicVo.setPic(e.getPic3());
                pics.add(sortingPicVo);
            }
            if (StringUtils.isNotBlank(e.getPic4())){
                SortingPicVo sortingPicVo = new SortingPicVo();
                sortingPicVo.setPic(e.getPic4());
                pics.add(sortingPicVo);
            }
        });
        return pics;
    }

    @Override
    public List<SortingPicVo> getGarbagePicByDate(String date) {
        List<SortingPicBo> sortingPicBos = baseMapper.selectPicByDate(date);
        List<SortingPicVo> pics = new ArrayList<>();
        sortingPicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic5())){
                SortingPicVo sortingPicVo = new SortingPicVo();
                sortingPicVo.setPic(e.getPic5());
                pics.add(sortingPicVo);
            }
            if (StringUtils.isNotBlank(e.getPic6())){
                SortingPicVo sortingPicVo = new SortingPicVo();
                sortingPicVo.setPic(e.getPic6());
                pics.add(sortingPicVo);
            }
        });
        return pics;
    }

    @Override
    public Integer getSumByDate(String date) {
        return baseMapper.selectSumByDate(date, null);
    }

    @Override
    public Integer getSumByDateAndCommunity(String date, String community) {
        return baseMapper.selectSumByDate(date, community);
    }

    @Override
    public List<SortingVo> queryListByDate(String date, String community) {
        LambdaQueryWrapper<Sorting> lqw = Wrappers.lambdaQuery();
        lqw.eq(Sorting::getDate,date);
        lqw.eq(Sorting::getDelFlag,"0");
        if (StringUtils.isNotEmpty(community)){
            lqw.eq(Sorting::getCommunity,community);
        }
        lqw.orderByDesc(Sorting::getActualStartTime);
        List<SortingVo> sortingVos = baseMapper.selectVoList(lqw);
        sortingVos.forEach(e->{
            e.setServiceTypeName(ServiceTypeEnum.SORTING.getTypeName());
        });
        return sortingVos;
    }
}
